package com.taobao.askwho.utils;


import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

import com.taobao.askwho.ao.TagAo;
import com.taobao.askwho.po.TagRelation;


public class LuceneUtils {
	Logger logger = Logger.getLogger(LuceneUtils.class);
	Analyzer analyzer = new IKAnalyzer();
	Directory directory = null;
	IndexWriter indexWriter = null;
	Map<String, String> searchDocHashMap = null;
	private String resultShowNumbers = "999";
	static IndexSearcher indexSearcher = null;
	private static LuceneUtils luceneUtil = new  LuceneUtils();
	public static LuceneUtils get() {
		return luceneUtil;
	}
	public String getResultShowNumbers() {
		return resultShowNumbers;
	}

	public void setResultShowNumbers(String resultShowNumbers) {
		this.resultShowNumbers = resultShowNumbers;
	}

	public LuceneUtils() {
		super();
	}
	/**
	 * 外部调用构造函数
	 */
	public void buildIndexOfLucene() {
		Map<String, String> searchDocHashMap = getAllDocFromDB();
		directory = null;
		indexSearcher = null;
		this.searchDocHashMap = searchDocHashMap;
		Map<String, String> docMap = searchDocHashMap;
		directory = new RAMDirectory();
		try {
			indexWriter = new IndexWriter(directory, analyzer, IndexWriter.MaxFieldLength.LIMITED);
			for (Map.Entry<String, String> entryset : docMap.entrySet()) {
				Document document = new Document();
				document.add(new Field("key", entryset.getKey(), Field.Store.YES, Field.Index.ANALYZED));
				document.add(new Field("value", entryset.getValue(), Field.Store.YES, Field.Index.ANALYZED));
				indexWriter.addDocument(document);
			}
		} catch (CorruptIndexException e) {
			logger.error("",e);
		} catch (LockObtainFailedException e) {
			logger.error("",e);
		} catch (IOException e) {
			logger.error("",e);
		} finally {
			closeIndexWriter();
		}
	}

	private void closeIndexWriter() {
		try {
			indexWriter.close();
		} catch (CorruptIndexException e) {
			logger.error("",e);
		} catch (IOException e) {
			logger.error("",e);
		}
	}

	/**
	 * 外部调用函数
	 *
	 * @param keyword
	 */
	public List<String> runTest(String keyword) {
		List<String> resultList = null;

		try {
			//实例化搜索器
			if (indexSearcher == null) {
				indexSearcher = new IndexSearcher(directory);
				indexSearcher.setSimilarity(new IKSimilarity());
			}
			//构造查询对象
			Query query = IKQueryParser.parse("value", keyword);
			if (query != null) {
				int resultShotNumber = Integer.parseInt(resultShowNumbers);
				TopDocs topDocs = indexSearcher.search(query, resultShotNumber);
				ScoreDoc[] scoreDoc = topDocs.scoreDocs;
				resultList = new ArrayList<String>(topDocs.scoreDocs.length);
				for (int i = 0; i < topDocs.scoreDocs.length; i++) {
					Document targetDocument = indexSearcher.doc(scoreDoc[i].doc);
					resultList.add(targetDocument.get("key"));
				}
			}
		} catch (CorruptIndexException e) {
			logger.error("",e);
		} catch (LockObtainFailedException e) {
			logger.error("",e);
		} catch (IOException e) {
			logger.error("",e);
		} finally {
			if (indexSearcher != null) {
				try {
					indexSearcher.close();
				} catch (IOException e) {
					logger.error("",e);
				}
			}
			if (directory != null) {
				try {
					directory.close();
				} catch (IOException e) {
					logger.error("",e);
				}
			}
		}
		return resultList;
	}

	public static HashMap<String, String> getAllDocFromDB() {
		HashMap<String, String> resultMap = new HashMap<String, String>();
		List<TagRelation> tagList = TagAo.get().queryForLuceneIndex();
		StringBuilder sb = new StringBuilder();
		for (TagRelation po : tagList) {
			sb.append(po.getTagName() != null ? po.getTagName() : "");
			resultMap.put(po.getUuid(), sb.toString());
			sb.setLength(0);
		}
		return resultMap;
	}

	public static void main(String[] args) {
		//		String database="jdbc:mysql://10.232.31.136:3306/askwho";
		//		String username="xiaoming";
		//		String password="sqlautoreview";
		//		LuceneUtils luceneTest = new LuceneUtils(getAllDocFromDB());
		//		String keyword = "测试";
		//		luceneTest.runTest(keyword);
	}
}
